
import GuideMgr from "./GuideMgr";
import { _decorator, Node, Button,Prefab, instantiate, __private } from 'cc';
import { bundleTool } from "./bundleTool";
const {ccclass, property} = _decorator;

export default class BaseView{
	protected mParent:BaseView = null;
	private _node:Node = null;
	private _isOpened:boolean;
	private  _isOnLoad:boolean;
	private  _zindex:number;
	private  _subViewList:Array<BaseView> = null;
	get isOpened(): boolean {return this._isOpened;}

	set isOpened(b:boolean) {this._isOpened = b;}

	get zIndex(): number {return this._zindex;}

	get node(): Node {return this._node;}

	set node(go: Node) {this._node = go;}

	set baseParent(go: BaseView) {this.mParent = go;}

	onLoad(){}

	onClose():void{}

	get url(): string {
		console.error(`未配置view url [${this.constructor.name}]`);

		return "";
	}

	openView(...params: unknown[]):void{
		this.isOpened = true;
		const mParent = params[0] as Node;

		this._zindex = params[1] as number;
		if (!this.node)
		{
			// 加载 AssetBundle 基类实现
			const arr = this.url.split(":");

			if (arr.length != 2) {
				console.error("路径配置错误\"[bundle:path]\":" + this.url);

				return;
			}
            
			const bundleName = arr[0];
			const urlName = arr[1];

			this._isOnLoad = true;
			bundleTool.instance().loadAsyncFromBundle(bundleName, urlName,Prefab).then((prefab:Prefab) => {
				this._isOnLoad = false;
				if (this.isOpened == false) return;
				if (prefab == null) {
					console.log(this.url + "路径错误..");

					return;
				}
            
				this.node = instantiate(prefab);
				this.node.name = this.constructor.name;
				this.node.setSiblingIndex(this._zindex);
				this.node.parent = mParent;
				this.node.active = true;
				GuideMgr.instance().checkAndGuide(this);
				this.onLoad()
			},(reason:string) => {
				console.error(reason);
			})
		}else{
			this.node.name = this.constructor.name;
			this.node.setSiblingIndex(this._zindex);
			this.node.parent = mParent;
			this.node.active = true;
			this.onLoad()
		}
	}

	openSubView<T extends BaseView>(view: __private.__types_globals__AbstractedConstructor<T>,
		viewdata:any=null,zindex:number=0,isone:boolean =true): boolean {
		if ( this.node?.isValid){
			if(isone&&this.node.getChildByName(view.name)!=null){
				return false;
			}

			if(this._subViewList==null){
				this._subViewList = [];
			}

			const v:BaseView = new view(viewdata);

			v.openView(this.node,zindex);
			v.baseParent = this;
			this._subViewList.push(v);

			return true;
		}

		return false;
	}

	getSubView<T extends BaseView>(view:{new(): T }):T {
		if(this._subViewList!= null){
			for (let i = 0; i < this._subViewList.length; i++) {
				const v:BaseView = this._subViewList[i];

				if(v.constructor.name==view.name){
					return v as T;
				}
			}
		}

		return null;
	}

	closeView():void {
		this.closeAllSubViews();
		if(this.mParent!= null){
			this.mParent.closeSubViewByName(this.node.name,false);
		}

		if (this.node?.isValid){
			this.node.destroy(); // 如果一个节点不再使用,请直接调用destroy 而不是removeFromParent，否则会导致内存泄漏
		}

		this._subViewList = null;
		this.node = null;
		this.onClose();
	}

	closeSubView<T extends BaseView>(view:{new(): T }):void {
		this.closeSubViewByName(view.name)
	}

	closeSubViewByName(name:string,isClean:boolean =true):void {
		if(this._subViewList==null){return;}
		let v:BaseView =null;

		for (let i = 0; i < this._subViewList.length; i++) {
			v = this._subViewList[i];
			if(v.constructor.name==name){
				if(isClean) v.closeView();
				this._subViewList.splice(i,1);
				v = null;
				break;
			}
		}
	}
	closeAllSubViews():void {
		if(this._subViewList==null){return;}
		let v:BaseView =null;

		for (let i = this._subViewList.length-1; i >=0; i--) {
			v = this._subViewList[i];
			v.closeView();
			this._subViewList.splice(i,1);
			v = null;
		}
	}

	// 节点下有二个子节点mask和content(包括了所有可见节点),均不需要设置button组件
	// 值为1，全屏悬浮框, 点击对话框区域外和域内，对话框无反应
	// 值为2，全屏悬浮框，点击对话框区域外和域内，关闭当前对话框 (适用奖励弹窗之类)
	// 值为3，全屏悬浮框，点击对话框区域外，关闭当前对话框
	setMutexMode(modeType:number):void{
		const uiMask = this.node.getChildByName('mask') || this.node.getChildByName('Mask');

		if(uiMask==null){ return; }
		const fcall = function(this:BaseView, btn:Button):void{
			if(modeType >=2&&btn.node==uiMask){
				this.closeView();
			}
		}

		if(modeType >2){
			const uiContent = this.node.getChildByName('content') || this.node.getChildByName('Content');

			if(uiContent==null){
				console.log("uiContent should not be null");

				return;
			}

			uiContent.addComponent(Button);
			uiContent.on("click", fcall.bind(this));
		}

		uiMask.addComponent(Button);
		uiMask.on("click", fcall.bind(this));
	}
}